/*eslint-disable*/
// 批量固定npm包版本任务脚本
const fs = require('fs');
const path = require('path');
const sub_app_ath = path.resolve();
const sub_apps = fs.readdirSync(sub_app_ath).filter((i) => /^sub|master/.test(i));

const { log } = console;
// console.log = (info) => log('\x1B[1;32m%s\x1B[0m', info);
console.error = (info) => log('\x1B[1;31m%s\x1B[0m', info);
console.log = (info) => log('\x1B[1;32m%s\x1B[0m', info);
// // 处理整体项目依赖
confirming('/');
// 处理子应用依赖 sub_apps = [master, sub-base]
if (Array.isArray(sub_apps) && sub_apps.length) {
	sub_apps.forEach((item) => {
		confirming(item + '/');
	});
}
function confirming(_opath) {
	// 读取node_modules中所有依赖文件夹
	let dir = path.resolve(__dirname, `../${_opath}/node_modules/`);

	// 获取package中的依赖，包括dependencies 和 devDependencies
	let packageInfo = _getPackageDependencies(_opath) || {};
	// console.log(JSON.stringify(packageInfo));
	// 根据packageInfo中的依赖获取node_modules中对应依赖的版本号存下来生成依赖版本map
	if (!packageInfo.dependencies) packageInfo.dependencies = {};
	if (!packageInfo.devDependencies) packageInfo.devDependencies = {};
	let versionMap = getAllFilePackage(dir, packageInfo) || {};
	// console.log(JSON.stringify(versionMap));
	let name = _opath === '/' ? '工程' : _opath;
	Object.keys(packageInfo.dependencies).forEach((item) => {
		if (!versionMap[item]) {
			return console.error(`-当前${name}-npm包中没有安装-${item}`);
		}
		packageInfo.dependencies[item] = versionMap[item];
	});
	Object.keys(packageInfo.devDependencies).forEach((item) => {
		if (!versionMap[item]) {
			return console.error(`当前${name}-npm包中没有安装-${item}`);
		}
		packageInfo.devDependencies[item] = versionMap[item];
	});
	// 重新写入package
	_writePackageDependencies(_opath);
	// 获取node_moudles中依赖版本
	function getAllFilePackage(opath, packageInfo) {
		let files = fs.readdirSync(opath);
		let regName = /@(.*?)@\d+/;
		let regVersion = /[a-z]+@(.*?)@@/;
		let packageVersionMap = {};
		// dependencies 和devDependencies 合并后好处理数据
		let dependCombines = [ ...Object.keys(packageInfo.dependencies), ...Object.keys(packageInfo.devDependencies) ];
		// console.log(JSON.stringify(dependCombines));
		files.forEach((item) => {
			// 使用cnpm 文件夹的目录会变为 _@babel_cli@7.12.1@@babel
			if (item.includes('@@')) {
				// 使用正则匹配依赖名称
				let matchNames = item.match(regName);
				let matchVesions = item.match(regVersion);
				let pageName = matchNames ? matchNames[1].replace('_', '/') : '';
				let pageVersion = matchVesions ? matchVesions[1] : '';
				if (!pageName || !pageVersion) return;
				pageName += '@';
				//package中名称前面有@，如：@babel/cli
				if (!dependCombines.includes(pageName)) return;
				packageVersionMap[pageName] = pageVersion;
				return;
			}
			// console.log(item);
			// 此处需兼容依赖中带有'/'的依赖，@vue/cli-plugin-babel格式，表示是@vue文件夹下cli-plugin-babel的文件
			let findArr = dependCombines.filter((findItem) => {
				// 如果是@vue/cli-plugin-babel格式
				if (findItem.includes('/')) {
					// 将带有层级文件的依赖处理数组进行判断
					let arr = findItem.split('/');
					if (arr.includes(item)) return true;
				}
				return findItem === item;
			});
			// 如果没有匹配到依赖
			if (!Array.isArray(findArr)) return;
			findArr.forEach((find) => {
				let packagePath = opath + '/' + find;
				let stat = fs.statSync(packagePath);

				// 如果不是文件
				if (!stat || !stat.isDirectory()) return;
				let itemFiles = fs.readdirSync(packagePath);

				itemFiles.forEach((citem) => {
					if (citem.includes('package')) {
						// console.log(`${item}-${citem}`, 'itemitemitemcitem');
						let package = JSON.parse(fs.readFileSync(path.resolve(packagePath, './package.json'), 'utf8'));
						packageVersionMap[find] = package.version;
					}
				});
			});
		});
		return packageVersionMap;
	}
	// 获取package中的依赖
	function _getPackageDependencies(_opath) {
		return JSON.parse(fs.readFileSync(path.resolve(__dirname, `../${_opath}package.json`), 'utf8'));
	}
	// 写入文件的依赖
	function _writePackageDependencies(_opath) {
		fs.writeFileSync(path.resolve(__dirname, `../${_opath}package.json`), JSON.stringify(packageInfo), {
			encoding: 'utf8'
		});
		let app = _opath.replace('/', '');
		console.log(`----------------${app ? app : '工程'} 确定依赖版本成功！---------------`);
	}
}
